<html lang="en"> <head> <script src="./d3/d3-4.7.3/d3.js"></script> </head> <body>
    <script type="text/javascript" charset="utf-8">
        // 1. 画布 && 大小
        var width = 400, height = 400;
        var svg = d3.select("body").append("svg").attr("width", width).attr("height", height);
        var padding = { left: 30, right: 30, top: 20, bottom: 20 }; // 给 SVG 的周边留一个空白, 最好不要将图形绘制到边界上
        // 2. 数据 && 比例尺
        var dataset = [10, 20, 30, 40, 33, 24, 12, 5];
        var xScale = d3.scaleBand() // x 轴的序数比例尺
            .domain(d3.range(dataset.length))
            .rangeRound([0, width - padding.left - padding.right]);  // 进行平均分配
        var yScale = d3.scaleLinear() // y 轴的线性比例尺
            .domain([0, d3.max(dataset)])
            .range([height - padding.top - padding.bottom, 0]);
        // 3. 坐标轴
        var xAxis = d3.axisBottom().scale(xScale) // 定义 x 轴, 在柱形图的下边
        var yAxis = d3.axisLeft().scale(yScale) // 定义 y 轴, 在柱形图的左边
        // 4. 添加矩形
        var rectPadding = 4; // 矩形之间的空白
        var rects = svg.selectAll(".MyRect").data(dataset).enter().append("rect")
            .attr("class", "MyRect") // 和 selectAll(".MyRect") 一起作用
            .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
            .attr("x", function(d, i) { return xScale(i) + rectPadding / 2; })
            .attr("width", xScale.bandwidth() - rectPadding)  // To find the width of the band in a band scale
            .attr("height", function(d) { return height - padding.top - padding.bottom - yScale(d); })
            // 以 y 轴为基准进行过度
            .attr("y",function(d){ return yScale(yScale.domain()[0]); })
            .transition()
            .delay(function(d,i){ return i * 200; })
            .duration(1000)
            .attr("y", function(d) { return yScale(d); });
        // 5. 添加文字元素
        var texts = svg.selectAll(".MyText").data(dataset).enter().append("text")
            .attr("class", "MyText")
            .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
            .attr("x", function(d, i) { return xScale(i) + rectPadding / 2 - 5; })  // 字和中线对齐
            .attr("dx", function() { return (xScale.bandwidth() - rectPadding) / 2; })
            .attr("dy", function(d) { return 20; })
            .text(function(d) { return d; })
            // 以 y 轴为基准进行过度
            .attr("y",function(d){ return yScale(yScale.domain()[0]) - 25; })  // 将文字显示在坐标轴上面
            .transition()
            .delay(function(d,i){ return i * 200; })  // 不同元素延迟不同时间
            .duration(1000)
            .attr("y", function(d) { return yScale(d) - 25; });
        // 6. 添加坐标轴
        svg.append("g").attr("class", "axis").attr("transform", "translate(" + padding.left + "," + (height - padding.bottom) + ")")
            .call(xAxis); // 添加 x 轴
        svg.append("g").attr("class", "axis").attr("transform", "translate(" + padding.left + "," + padding.top + ")")
            .call(yAxis); // 添加 y 轴
        // 7. 在添加文字元素和矩形元素的时候, 启动过渡效果, 让各柱形和文字缓慢升至目标高度
    </script> </body> </html>
